package com.yycx.module.bus.provider.service.hy.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yycx.common.base.entity.EntityMap;
import com.yycx.common.base.utils.FlymeUtils;
import com.yycx.common.mybatis.base.service.impl.BaseServiceImpl;
import com.yycx.common.mybatis.model.ResultBody;
import com.yycx.common.mybatis.query.CriteriaQuery;
import com.yycx.common.mybatis.query.CriteriaSave;
import com.yycx.common.security.OpenHelper;
import com.yycx.module.admin.client.entity.BaseUser;
import com.yycx.module.bus.client.entity.hy.BusErpOrder;
import com.yycx.module.bus.client.entity.hy.BusErpOrderDetails;
import com.yycx.module.bus.provider.mapper.hy.BusErpOrderMapper;
import com.yycx.module.bus.provider.service.hy.BusErpOrderDetailsService;
import com.yycx.module.bus.provider.service.hy.BusErpOrderService;
import com.yycx.module.bus.provider.service.lc.SyncVoucherService;
import com.yycx.module.system.client.entity.SysCompany;
import com.yycx.module.system.provider.service.SysCompanyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 海鹰erp订单接口实现类
 *
 * @author flyme
 * @date 2023-02-07
 */
@Service
@DSTransactional
public class BusErpOrderServiceImpl extends BaseServiceImpl<BusErpOrderMapper, BusErpOrder> implements BusErpOrderService {

    @Autowired
    BusErpOrderDetailsService busErpOrderDetailsService;

    @Autowired
    SyncVoucherService syncService;

    @Autowired
    private SysCompanyService sysCompanyService;

    @Override
    public ResultBody beforeAdd(CriteriaSave cs, BusErpOrder beo, EntityMap extra) {
        return ResultBody.ok();
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<BusErpOrder> cq, BusErpOrder beo, EntityMap requestMap) {


        String beginDate = requestMap.get("beginDate");
        String endDate = requestMap.get("endDate");
        Integer ybState = requestMap.getInt("ybState");
        if (StrUtil.isNotEmpty(beginDate)) {
            cq.ge("orderDate", beginDate);
        }
        if (StrUtil.isNotEmpty(endDate)) {
            cq.le("orderDate", endDate);
        }
        cq.eq("orderType", cq.getParams("orderType"));
        cq.like("orderNo", cq.getParams("orderNo"));
        cq.like("voucherHandleState", cq.getParams("voucherHandleState"));
        cq.like("beo.companyName", cq.getParams("companyName"));
        cq.like("voucher", cq.getParams("voucher"));
        //cq.like("beo.companyId", cq.getParams("hyDwCode"));

        if(FlymeUtils.isNotEmpty(ybState)&&ybState.equals(1)){
            cq.eq("beo.saleAmount", 0);
        }
        Object companyId =  OpenHelper.getCompanyId();
        cq.eq("beo.companyId", companyId);
        cq.orderByDesc("beo.orderDate,beo.updateTime");
        cq.select(BusErpOrder.class, "orderId", "orderType", "saleType", "orderNo", "orderDate", "saleNum", "saleAmount", "saleManName", "invoice", "companyId", "companyCode", "companyName", "deptId", "voucherCount", "deptCode", "deptName", "createTime", "updateTime", "voucherHandleState", "operateUser", "voucher", "orderSource", "erpDbName", "hyDwCode", "sign", "reviewed", "receiptAmount");
        cq.select("baseuser.nickName", "company.companyName voucherCompanyName");
        cq.createJoin(BaseUser.class).setMainField("operateUser").setJoinField("userId");
        //cq.createJoin(SysCompany.class).setMainField("hyDwCode").setJoinField("companyCode and  company.companyId = (select max(companyId) from sys_company where companyCode= '" + companyCode + "')");
        cq.createJoin(SysCompany.class).setMainField("companyId").setJoinField("companyId");

        return ResultBody.ok();
    }


    @Override
    public ResultBody createVoucher(Map params) {
        List<String> orderNos = StrUtil.split(params.get("orderNo").toString(), ',');
        //syncService.createVoucher(orderNos, MapUtil.getStr(params, "orderType"), OpenHelper.getUser(), MapUtil.getStr(params, "day", ""));
        boolean flag = this.update(new UpdateWrapper<BusErpOrder>().lambda().set(BusErpOrder::getUpdateTime, DateUtil.date()).set(BusErpOrder::getOperateUser, OpenHelper.getUserId()).set(BusErpOrder::getVoucherHandleState, 2).eq(BusErpOrder::getOrderType, params.get("orderType")).in(BusErpOrder::getOrderNo, orderNos));
        return ResultBody.ok(flag);
    }

    @Override
    public ResultBody mergeVoucher(Map params) {
        List<String> orderNos = StrUtil.split(params.get("orderNo").toString(), ',');
      //  syncService.mergeVoucher(orderNos, MapUtil.getStr(params, "orderType"), OpenHelper.getUser(), MapUtil.getStr(params, "day", ""));
        boolean flag = this.update(new UpdateWrapper<BusErpOrder>().lambda().set(BusErpOrder::getUpdateTime, DateUtil.date()).set(BusErpOrder::getOperateUser, OpenHelper.getUserId()).set(BusErpOrder::getVoucherHandleState, 2).eq(BusErpOrder::getOrderType, params.get("orderType")).in(BusErpOrder::getOrderNo, orderNos));
        return ResultBody.ok(flag);
    }

    @Override
    public ResultBody monthVoucher(Map params) {
        String companyCode=MapUtil.get(params,"companyCode",String.class);
        String currentMonth = StrUtil.isNotEmpty(MapUtil.getStr(params, "month", "")) ? MapUtil.getStr(params, "month", "") : DatePattern.NORM_MONTH_FORMAT.format(DateUtil.date());
        Map<String, Object> map = sysCompanyService.getMap(new QueryWrapper<SysCompany>().select("companyCode").eq("companyId", companyCode));
        List<Map<String, Object>> orderList = this.listMaps(new QueryWrapper<BusErpOrder>().lambda().select(BusErpOrder::getOrderNo).eq(BusErpOrder::getOrderType, params.get("orderType").toString()).eq(BusErpOrder::getHyDwCode, companyCode).likeRight(BusErpOrder::getOrderDate, currentMonth));
        if (CollUtil.isNotEmpty(orderList)) {
            List<String> orderNo = orderList.stream().map(o -> o.get("orderNo").toString()).collect(Collectors.toList());
           // syncService.mergeVoucher(orderNo, MapUtil.getStr(params, "orderType"), OpenHelper.getUser(), MapUtil.getStr(params, "day", ""));
            this.update(new UpdateWrapper<BusErpOrder>().lambda().set(BusErpOrder::getUpdateTime, DateUtil.date()).set(BusErpOrder::getOperateUser, OpenHelper.getUserId()).set(BusErpOrder::getVoucherHandleState, 2).eq(BusErpOrder::getOrderType, params.get("orderType")).in(BusErpOrder::getOrderNo, orderNo));
        }
        return ResultBody.ok();
    }

    @Override
    public BusErpOrder findByOrderNoAndType(String orderNo, Integer orderType) {
        CriteriaQuery<BusErpOrder> cq=new CriteriaQuery<>(BusErpOrder.class);
        cq.eq(true,"orderNo",orderNo);
        cq.eq(true,"orderType",orderType);
        return getOne(cq,false);
    }

    @Override
    public ResultBody sampleVoucher(MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            ExcelReader excelReader = ExcelUtil.getReader(inputStream);
            List<List<Object>> read1 = excelReader.read(1, excelReader.getRowCount());
            String month = read1.get(0).get(0).toString().split("--")[0];
            List<List<Object>> read = excelReader.read(5, excelReader.getRowCount());

            //组装商品金额
            List<BusErpOrderDetails> list = new ArrayList<>();
            for (List<Object> objects : read) {
                if (objects.get(2).toString().length()==7) {
                    BusErpOrderDetails details = new BusErpOrderDetails();
                    details.setProductName(objects.get(3).toString());
                    details.setProductCode(objects.get(2).toString());
                    details.setProductCodeSource(objects.get(2).toString());
                    details.setProductNum((int) (Double.valueOf(objects.get(5).toString()) + Double.valueOf(objects.get(8).toString())));
                    details.setProductSaleAmount(new BigDecimal(objects.get(7).toString()).add(new BigDecimal(objects.get(10).toString())));
                    details.setProductPrice(details.getProductNum() == 0 ? new BigDecimal(0) : details.getProductSaleAmount().divide(new BigDecimal(details.getProductNum()), BigDecimal.ROUND_HALF_UP));
                    list.add(details);
                }
            }

            if (CollUtil.isEmpty(list)) {
                return ResultBody.failed(month + "未查询到商品");
            }
            //生成样品凭证
            syncService.sampleVoucher(month.replace(".", "-"), list, OpenHelper.getUser());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultBody.ok();
    }

    @Override
    public ResultBody createCost(Map params) {
        //生成成本凭证
        syncService.costVoucher(params);
        return ResultBody.ok();
    }

    @Override
    public ResultBody createPayment(Map params) {
        //付款凭证
        syncService.createPayment(params);
        return ResultBody.ok();
    }

    @Override
    public ResultBody getCompany(Map params) {
        List<SysCompany> byAccount = sysCompanyService.getByAccount(OpenHelper.getUserName());
        List<SysCompany> collect = byAccount.stream().filter(c -> c.getCompanyErpState().equals(1)).sorted(Comparator.comparing(e -> e.getCompanyId())).collect(Collectors.toList());
        return ResultBody.ok(collect);
    }


    @Override
    public ResultBody updateOrder(Map params) {
        syncService.updateOrder(params);
        return ResultBody.ok();
    }
}
